package com.imohoo.shanpao;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import com.google.gson.Gson;
import com.imohoo.jni.Main;
import com.imohoo.libs.converter.SpFile;
import com.imohoo.libs.converter.SpJsonConverterFactory;
import com.imohoo.libs.converter.SpRequest;
import com.imohoo.libs.converter.SpResponse;
import com.imohoo.libs.converter.adapter.ErrorHandlingCallAdapterFactory;
import com.imohoo.libs.converter.adapter.MyCall;
import com.imohoo.libs.converter.adapter.MyCallback;
import com.imohoo.shanpao.git.GitHubService;
import com.imohoo.shanpao.git.Repo;
import com.imohoo.shanpao.request.ShanpaoService;
import com.imohoo.shanpao.request.ZanRequest;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;

/**
 * Created by zhaobo on 2017/1/3.
 */

public class MainActivity extends Activity {
    public static long user_id = 20;
    public static String user_token = "63b543010365da697585903d02e54d47";
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Main.init(this, 1);
        setContentView(R.layout.activity_main);
//        FileUploadRequest fileRequest = new FileUploadRequest();
//        fileRequest.setPrefix(FileUploadRequest.prefix_circle);
//        fileRequest.setUser_id(user_id);
//        fileRequest.setToken(user_token);
//        uploadFile(fileRequest, "/storage/emulated/0/Pictures/Picture_01_Shark.jpg");
        textView = (TextView) findViewById(R.id.textView);
    }

    public void aa(View view) {
//        listGithub();
//        listZan();
//        FileUploadRequest fileRequest = new FileUploadRequest();
//        fileRequest.setPrefix(FileUploadRequest.prefix_circle);
//        fileRequest.setUser_id(user_id);
//        fileRequest.setToken(user_token);
//        uploadFile2(fileRequest, "/storage/emulated/0/Pictures/Picture_01_Shark.jpg");

//        long begin = System.currentTimeMillis();
//        for (int i = 0; i < 100; i++) {
//            listZan2();
//        }
//        long yu = System.currentTimeMillis() - begin;
//        textView.setText("100次平均执行时间 = " + yu);


        new Thread(new Runnable() {
            @Override
            public void run() {
                listZan();
//                listGithub();
            }
        }).start();
    }

    private void listGithub() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.github.com/")
                .addCallAdapterFactory(new ErrorHandlingCallAdapterFactory())
                .addConverterFactory(retrofit2.converter.gson.GsonConverterFactory.create())
                .build();

        GitHubService service = retrofit.create(GitHubService.class);
//        Call<List<Repo>> call = service.listRepos("axter");
//        call.enqueue(new Callback<List<Repo>>() {
//            @Override
//            public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
//                System.out.println(response.body().size());
//            }
//
//            @Override
//            public void onFailure(Call<List<Repo>> call, Throwable t) {
//                t.printStackTrace();
//            }
//        });
        MyCall<List<Repo>> call = service.listRepos("axter");
        call.enqueue(new MyCallback<List<Repo>>() {
            @Override
            public void success(Response<List<Repo>> response) {
                System.out.println();
            }

            @Override
            public void unauthenticated(Response<?> response) {
                System.out.println();
            }

            @Override
            public void clientError(Response<?> response) {
                System.out.println();
            }

            @Override
            public void serverError(Response<?> response) {
                System.out.println();
            }

            @Override
            public void networkError(IOException e) {
                System.out.println();
            }

            @Override
            public void unexpectedError(Throwable t) {
                System.out.println();
            }
        });
    }

    private void listZan() {
        try {
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init((KeyStore) null);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
            if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
                throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
            }
            X509TrustManager trustManager = (X509TrustManager) trustManagers[0];

            OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
                    .sslSocketFactory(getSSLSocketFactory(this, new int[]{R.raw.shanpaossl}), trustManager)
                    //.hostnameVerifier(getHostnameVerifier(new String[]{"myrunners.com", "*.myrunners.com"}))
                    .connectTimeout(30, TimeUnit.SECONDS)
                    .readTimeout(30, TimeUnit.SECONDS)
                    .writeTimeout(30, TimeUnit.SECONDS)
                    .build();

            Retrofit retrofit = new Retrofit.Builder()
                    .client(mOkHttpClient)
                    .baseUrl("https://dev-api.myrunners.com/")
                    .addConverterFactory(SpJsonConverterFactory.create())
                    .build();

            ShanpaoService service = retrofit.create(ShanpaoService.class);


//            String json = new Gson().toJson(getMsgZanListRequest(1, 0));
//            HashMap<String, Object> request = new HashMap<>();
//            request.put("api_version", "2_7");
//            request.put("APIDATA", new String(Base64.encodeBase64(Main.abc(json.getBytes(), Main.ENCRYPT, 1))));

//            Call<SpResponse<HashMap>> call = service.listZan(request);
//            call.enqueue(new Callback<SpResponse<HashMap>>() {
//                @Override
//                public void onResponse(Call<SpResponse<HashMap>> call, Response<SpResponse<HashMap>> response) {
//                    System.out.println(response.body().toString());
//                }
//
//                @Override
//                public void onFailure(Call<SpResponse<HashMap>> call, Throwable t) {
//                    t.printStackTrace();
//                }
//            });


//            Call<SpResponse<HashMap>> call = service.listZan1(getMsgZanListRequest(1, 0));
//            call.enqueue(new Callback<SpResponse<HashMap>>() {
//                @Override
//                public void onResponse(Call<SpResponse<HashMap>> call, Response<SpResponse<HashMap>> response) {
//                    System.out.println(response.body().toString());
//                }
//
//                @Override
//                public void onFailure(Call<SpResponse<HashMap>> call, Throwable t) {
//                    t.printStackTrace();
//                }
//            });

            Call<SpResponse<HashMap>> call = service.listZan1(new ZanRequest().setAction(1).setPage(0));
//            Call<SpResponse<HashMap>> call = service.listZan2(new SpRequest().add("action", 1).add("page", 0));
            call.enqueue(new Callback<SpResponse<HashMap>>() {
                @Override
                public void onResponse(Call<SpResponse<HashMap>> call, Response<SpResponse<HashMap>> response) {
                    textView.setText(new Gson().toJson(response.body()));
                }

                @Override
                public void onFailure(Call<SpResponse<HashMap>> call, Throwable t) {
                    t.printStackTrace();
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    Retrofit retrofit = null;
    private void listZan2() {
        try {
            if (retrofit == null) {
                TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                trustManagerFactory.init((KeyStore) null);
                TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
                if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
                    throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
                }
                X509TrustManager trustManager = (X509TrustManager) trustManagers[0];

                OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
                        .sslSocketFactory(getSSLSocketFactory(this, new int[]{R.raw.shanpaossl}), trustManager)
                        .hostnameVerifier(getHostnameVerifier(new String[]{"myrunners.com", "*.myrunners.com"}))
                        .connectTimeout(30, TimeUnit.SECONDS)
                        .readTimeout(30, TimeUnit.SECONDS)
                        .writeTimeout(30, TimeUnit.SECONDS)
                        .build();

                retrofit = new Retrofit.Builder()
                        .client(mOkHttpClient)
                        .baseUrl("https://dev-api.myrunners.com/")
                        .addConverterFactory(SpJsonConverterFactory.create())
                        .build();
            }
            ShanpaoService service = retrofit.create(ShanpaoService.class);


//            String json = new Gson().toJson(getMsgZanListRequest(1, 0));
//            HashMap<String, Object> request = new HashMap<>();
//            request.put("api_version", "2_7");
//            request.put("APIDATA", new String(Base64.encodeBase64(Main.abc(json.getBytes(), Main.ENCRYPT, 1))));

//            Call<SpResponse<HashMap>> call = service.listZan(request);
//            call.enqueue(new Callback<SpResponse<HashMap>>() {
//                @Override
//                public void onResponse(Call<SpResponse<HashMap>> call, Response<SpResponse<HashMap>> response) {
//                    System.out.println(response.body().toString());
//                }
//
//                @Override
//                public void onFailure(Call<SpResponse<HashMap>> call, Throwable t) {
//                    t.printStackTrace();
//                }
//            });


//            Call<SpResponse<HashMap>> call = service.listZan1(getMsgZanListRequest(1, 0));
//            call.enqueue(new Callback<SpResponse<HashMap>>() {
//                @Override
//                public void onResponse(Call<SpResponse<HashMap>> call, Response<SpResponse<HashMap>> response) {
//                    System.out.println(response.body().toString());
//                }
//
//                @Override
//                public void onFailure(Call<SpResponse<HashMap>> call, Throwable t) {
//                    t.printStackTrace();
//                }
//            });

            Call<SpResponse<HashMap>> call = service.listZan1(new ZanRequest().setAction(1).setPage(0));
//            Call<SpResponse<HashMap>> call = service.listZan2(new SpRequest().add("action", 1).add("page", 0));
            call.enqueue(new Callback<SpResponse<HashMap>>() {
                @Override
                public void onResponse(Call<SpResponse<HashMap>> call, Response<SpResponse<HashMap>> response) {
                    System.out.println(new Gson().toJson(response.body()));
                }

                @Override
                public void onFailure(Call<SpResponse<HashMap>> call, Throwable t) {
                    t.printStackTrace();
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    private void uploadFile2(FileUploadRequest request, String filePath) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://dev-file.myrunners.com/")
                .addConverterFactory(SpJsonConverterFactory.create())
                .build();

        ShanpaoService service = retrofit.create(ShanpaoService.class);
        Call<FileUploadResponse> call = service.uploadFile2(new SpFile(request, request.getFiles(), filePath));
        call.enqueue(new Callback<FileUploadResponse>() {
            @Override
            public void onResponse(Call<FileUploadResponse> call, Response<FileUploadResponse> response) {
                textView.setText(response.body().getData().get(0).getFile_url());
            }

            @Override
            public void onFailure(Call<FileUploadResponse> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }

    private void uploadFile(FileUploadRequest request, String filePath) {
        File file = new File(filePath);
        RequestBody requestFile = RequestBody.create(null, file);
        MultipartBody.Part body =
                MultipartBody.Part.createFormData("files", file.getName(), requestFile);

        HashMap<String, RequestBody> requestBods = new HashMap<>();
        for (Map.Entry<String, Object> keyset : request.entrySet()) {
            requestBods.put(keyset.getKey(), RequestBody.create(null, keyset.getValue().toString()));
        }

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://dev-file.myrunners.com/")
                .addConverterFactory(SpJsonConverterFactory.create())
                .build();

        ShanpaoService service = retrofit.create(ShanpaoService.class);
        Call<FileUploadResponse> call = service.uploadFile(body, requestBods);
        call.enqueue(new Callback<FileUploadResponse>() {
            @Override
            public void onResponse(Call<FileUploadResponse> call, Response<FileUploadResponse> response) {
                System.out.println(response.body().getData().get(0).getFile_url());
            }

            @Override
            public void onFailure(Call<FileUploadResponse> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }

    public static SpRequest getMsgZanListRequest(int action, int page) {
        return new SpRequest()
                //.addHead("SnsApi", "getUserHitsList")
                .add("action", action)
                .add("page", page);
    }


    protected static SSLSocketFactory getSSLSocketFactory(Context context, int[] certificates) {
        if (context == null) {
            throw new NullPointerException("context == null");
        }

        CertificateFactory certificateFactory;
        try {
            certificateFactory = CertificateFactory.getInstance("X.509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null, null);

            for (int i = 0; i < certificates.length; i++) {
                InputStream certificate = context.getResources().openRawResource(certificates[i]);
                keyStore.setCertificateEntry(String.valueOf(i), certificateFactory.generateCertificate(certificate));

                if (certificate != null) {
                    certificate.close();
                }
            }
            SSLContext sslContext = SSLContext.getInstance("TLS");
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    protected static HostnameVerifier getHostnameVerifier(final String[] hostUrls) {
        HostnameVerifier TRUSTED_VERIFIER = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                boolean ret = false;
                for (String host : hostUrls) {
                    if (host.equalsIgnoreCase(hostname)) {
                        ret = true;
                    }
                }
                return ret;
            }
        };
        return TRUSTED_VERIFIER;
    }
}
